package s

import (
	"github.com/maxwellhealth/bongo"
	"github.com/graphql-go/handler"
	"github.com/graphql-go/graphql"
	"log"
	"gopkg.in/mgo.v2/bson"
	"github.com/graphql-go/graphql/language/ast"
	"time"
)
//
//func coerceFloat(value interface{}) interface{} {
//	switch value := value.(type) {
//	case bool:
//		if value == true {
//			return 1.0
//		}
//		return 0.0
//	case int:
//		return float64(value)
//	case float32:
//		return value
//	case float64:
//		return value
//	case string:
//		val, err := strconv.ParseFloat(value, 0)
//		if err != nil {
//			return nil
//		}
//		return val
//	}
//	return 0.0
//}

func SerialObjectID(value interface{}) interface{} {
	switch value := value.(type) {
	case bson.ObjectId:
		return value.Hex()
	case string:
		return value
	}
	return nil
}


// Float is the GraphQL float type definition.
var TypeObjectID = graphql.NewScalar(graphql.ScalarConfig{
	Name: "TypeObjectID",
	Description: "ObjectID mongodb ",
	Serialize:  SerialObjectID,
	ParseValue: SerialObjectID,
	ParseLiteral:  func(valueAST ast.Value) interface{} {
		switch valueAST := valueAST.(type) {
		case *ast.StringValue:
			return valueAST.Value
		}
		return nil
	},
})

type Prod struct {
	bongo.DocumentBase `bson:",inline"`
	Pname  string   //商品名称
	Bname  string   //品牌名称
	Price  float32   //售价
	Uprice float32   //吊牌价
	Code   string   //货号updatedAt
	Tag    string //分类
	DaoGou int //用户
	Des string
	Status int ` json:"status,omitempty" gorm:"column:Status"`
}
type ProdV struct {
//	ID string  ` json:",omitempty" gorm:"column:Id;primary_key"`	//自增Id
	Id       bson.ObjectId `bson:"_id,omitempty" json:"_id"`
	Created  time.Time     `bson:"_created" json:"_created"`
	Modified time.Time     `bson:"_modified" json:"_modified"`
	Pname  string   //商品名称
	Bname  string   //品牌名称
	Price  float32   //售价
	Uprice float32   //吊牌价
	Code   string   //货号updatedAt
	Tag    string //分类
	DaoGou int //用户
	Des string
	Status int ` json:"status,omitempty" gorm:"column:Status"`
//	C      []string //颜色
//	S      []string	//尺码
//	Imgs map[string][]string //图片
//	UpdatedAt	*time.Time
}


var HandlerProd *handler.Handler;
func init(){
//	type DocumentBase struct {
//		Id       bson.ObjectId `bson:"_id,omitempty" json:"_id"`
//		Created  time.Time     `bson:"_created" json:"_created"`
//		Modified time.Time     `bson:"_modified" json:"_modified"`
//

	typeDocumentBase := graphql.NewObject(graphql.ObjectConfig{
		Name: "DocumentBase",
		Fields: graphql.Fields{
			"Id": &graphql.Field{
				Name: "Id",
				Description:"商品ID",
				Type: TypeObjectID,
			},
			"Created": &graphql.Field{
				Name: "Created",
				Description:"Created",
				Type: graphql.String,
			},
		},
	})
//	type EnumValueConfig struct {
//		Value             interface{} `json:"value"`
//		DeprecationReason string      `json:"deprecationReason"`
//		Description       string      `json:"description"`
//	}


	typeProd := graphql.NewObject(graphql.ObjectConfig{
		Name: "Prod",
		Fields: graphql.Fields{

			"Id": &graphql.Field{
				Name: "Id",
				Description:"商品ID",
				Type: TypeObjectID,
			},
			"Created": &graphql.Field{
				Name: "Created",
				Description:"Created",
				Type: graphql.String,
			},
			"DocumentBase": &graphql.Field{
				Name: "DocumentBase",
				Description:"DocumentBase",
				Type: typeDocumentBase,
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					product:=p.Source.(ProdV)
				return bongo.DocumentBase{Id:product.Id,Created:product.Created},nil
				},
			},
			"Pname": &graphql.Field{
				Name: "pname",
				Description:"商品名称",
				Type: graphql.String,
			},
			"Bname": &graphql.Field{
				Name: "bname",
				Description:"品牌名称",
				Type: graphql.String,
			},
			"Price": &graphql.Field{
				Name: "price",
				Description:"售价",
				Type: graphql.String,
			},
			"Uprice": &graphql.Field{
				Name: "Uprice",
				Description:"吊牌价",
				Type: graphql.String,
			},
			"Code": &graphql.Field{
				Name: "Code",
				Description:"sku code",
				Type: graphql.String,
			},
			"Tag": &graphql.Field{
				Name: "Tag",
				Description:"Tag",
				Type: graphql.String,
			},
//			"Pname": &graphql.Field{
//				Name: "name",
//				Description:"test des",
//				Type: graphql.String,
//			},
			"DaoGou": &graphql.Field{
				Name: "DaoGou",
				Description:"DaoGou",
				Type: graphql.String,
			},
			"Des": &graphql.Field{
				Name: "Des",
				Description:"商品描述",
				Type: graphql.String,
//				Resolve: func (p graphql.ResolveParams) (interface{}, error) {
//					return "testf value", nil
//				},
			},
		},
	})
	typeEnum := graphql.NewEnum(graphql.EnumConfig{
		Name:"tagsEnum",
		Values:graphql.EnumValueConfigMap{
			"a222":&graphql.EnumValueConfig{Value:"黄金",Description:"黄金"},
			"a221": &graphql.EnumValueConfig{Value:"衣",Description:"衣"},
		},
	})
	log.Println(typeEnum.Error())

	Query := graphql.NewObject(graphql.ObjectConfig{
		Name: "Query",
		Fields: graphql.Fields{
			"prod": &graphql.Field{
				Name: "prod",
				Description:"产品信息",
				Type: typeProd,
				Args: graphql.FieldConfigArgument{
					"id": &graphql.ArgumentConfig{
						Type: graphql.ID,
					},
				},
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					id := p.Args["id"].(string)
					return GetProdByID(id)
				},
			},
			"prods": &graphql.Field{
				Name: "prods",
				Description:"产品列表信息",
				Type: graphql.NewList(typeProd),
				Args: graphql.FieldConfigArgument{
					"tag": &graphql.ArgumentConfig{
						Type: typeEnum,
						Description: "类目名称",
					},
					"bname": &graphql.ArgumentConfig{
						Type: graphql.String,
						Description: "品牌名称",
					},
					"perPage": &graphql.ArgumentConfig{
						Type: graphql.Int,
						Description: "每页显示数量",
						DefaultValue:20,
					},
					"page": &graphql.ArgumentConfig{
						Type: graphql.Int,
						Description: "页码,从1开始",
						DefaultValue:1,
					},
				},
				Resolve: func(p graphql.ResolveParams) (interface{}, error) {
					con:= map[string]interface{}{}
					if p.Args["tag"] !=nil {
						con["tag"]=p.Args["tag"]
					}
					if p.Args["bname"] !=nil {
						con["bname"]=p.Args["bname"]
					}
					perPage := p.Args["perPage"].(int)
					page := p.Args["page"].(int)
					return FindByCon(perPage,page,con)

				},
			},
		},
	})
	log.Println(Query.Error())

	myNameSchema, err := graphql.NewSchema(graphql.SchemaConfig{Query, nil, nil, nil, nil})
	if err != nil {
		log.Fatal(err)
	}

	HandlerProd = handler.New(&handler.Config{
		Schema: &myNameSchema,
		Pretty: true,
	})
}




//"{"_id":"","_created":"0001-01-01T00:00:00Z",
// "_modified":"0001-01-01T00:00:00Z","Pname":""
// ,"Bname":"","Price":"","Uprice":"","Code":""
// ,"Tag":"","DaoGou":0,"Des":"","status":12}

type Prod1 struct {
					 //	ID string  ` json:",omitempty" gorm:"column:Id;primary_key"`	//自增Id
	Pname  string   //商品名称
	Bname  string   //品牌名称
	Price  float32   //售价
	Uprice float32   //吊牌价
	Code   string   //货号updatedAt
	Tag    string //分类
	DaoGou int //用户
	Des string
	Status int ` json:"status,omitempty" gorm:"column:Status"`
					 	C      []string //颜色
					 	S      []string	//尺码
					 //	Imgs map[string][]string //图片
					 //	UpdatedAt	*time.Time
}
